AWS Chalice を使って、Amazon Bedrock Slack Appを作成してみた
AWS事業本部の梶原@福岡オフィスです。
先日作成したSlack Appに対して、Amazon Bedrockの検証の為に、応答部分を変更してAmazon Bedrock Slack Appを作成してみます。
ということで、以前作成したSlack Appをベースに
Amazon BedrockのAPIを呼び出して、回答を作成し、返信する Slack Appを作成してみます
はじめに
以下の技術、サービスを使っています。詳しくは参考情報や、リンクなどをご参照ください
- Amazon Bedrock
- 本日GAされました。リリース内容などは以下のブログなどをご参考ください
- https://dev.classmethod.jp/articles/amazon-bedrock-ga/
- https://dev.classmethod.jp/articles/breaing-news-amazon-bedrock-was-released/
- Slack (Slack Bolt for Python)
- Slack 純正のSDK
- Chalice(Python Serverless Microframework for AWS)
- ちょっと情報は少ないですが、デプロイと削除が1撃で手軽にできるので選定しました
前提条件
- AWS アカウントまた以下サービスへの権限が必要です
- Amazon Bedrock
- AWS IAM
- AWS Lambda
- Amazon API Gateway
- Amazon S3
- Slack
- アプリケーションがインストール可能なこと
事前準備
Amazon Bedrock
AWS コンソールにて、Amazon Bedrock の使用可能なモデルの確認を行って下さい。必要応じてBedrockで使用するモデルへのアクセスをリクエストしてください。
今回は、AL21 Labs の Jurassic-2 Mid を使用しますので、該当の項目が[Access granted]になっていることを確認してください
Amazon Bedrock > Model access リージョン:us-east-1
https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess
AWS 環境設定
Chaliceでデプロイをおこなうので、事前にCredential等を設定してください
Bedrock の使用可能なリージョン us-east-1 を指定します
$ aws configure AWS Access Key ID [None]: xxxxx AWS Secret Access Key [None]: xxxxx Default region name [ap-northeast-1]: us-east-1 Default output format [None]:
Pythonの環境設定
Python 3.10 の環境設定をします。
以降の処理はPython3.10 のvenv環境での実行を想定しています
$ python3.10 -m venv .venv310 $ source .venv310/bin/activate $ python --version Python 3.10.12 $ pip --version pip 22.0.2 from .venv310/lib/python3.10/site-packages/pip (python 3.10)
各種pipパッケージのインストール
Slack, Chalice, Boto3, のパッケージをインストールしておきます。
※ Boto3 SDK はAmazon Bedrock の対応が含まれる 1.28.57 以上を指定してください
requirements.txt
slack_bolt chalice boto3 >= 1.28.57
尚、requirements.txt に記載したファイルはAWS Lambdaにデプロイされる際にLambda Layerに一緒にパッケージングされます。便利!
$ pip install -r requirements.txt
Chalice、Slackについて
このアプリケーションの元となる、Chalice, Slackの部分はこちらのエントリーでご案内していますのでご参考ください。
やってみた
Slack Bolt for Pythonのclone
実際は、Chalice の部分だけで良いのですが、まとめて取得します。
$ git clone https://github.com/slackapi/bolt-python.git
Chalice
Slack Bolt for Python にChaliceのサンプルがあるので流用します。
$ cd bolt-python/examples/aws_chalice/
メンションの応答の実装部分に、AWS Bedrock APIの処理を追加して、メンションされた内容に対して、AWS Titan モデルで回答を作成して返すようにしてみます
なお、Amazon Bedrockのコードは公開されているAWS サンプルのBedrock のワークショップのコードや、API リファレンスを参考にしています。
環境変数設定
.chalice フォルダにある Chalice(AWS Lambda)の環境変数を設定します。
Bedrockの呼び出しの権限などは、以下で設定するLambdaのロールに対して行いますので、特にここでAPIキーなどの設定は必要ありません。
現在はLambdaに含まれているboto3のバージョンが古いため、automatic_layer でboto3を含んだレイヤーを自動作成してLambaで使用します。
config.json
{ "version": "2.0", "app_name": "bolt-chalice-bedrock", "stages": { "dev": { "api_gateway_stage": "api", "environment_variables": { "SLACK_BOT_TOKEN": "xoxb-xxxxx", "SLACK_SIGNING_SECRET": "xxxxxx" }, "autogen_policy": false, "automatic_layer": true } } }
Amazon Bedrock を呼び出す際に必要なポリシーをpolicy-dev.jsonに設定します。
以下で、bedrockの呼び出しをすべて許可状態にしています。必要に応じて、権限を絞る等の対応を実施してください
{
"Effect": "Allow",
"Action": [
"bedrock:*"
],
"Resource": "*"
}
policy-dev.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "bedrock:*" ], "Resource": "*" } ] }
実装部分
既存の処理はSlackアプリに対して、メンションされた場合(”app_mention”)に、say()でメッセージを返していますので、この部分に変更を行います
元のコード
@bolt_app.event("app_mention") def handle_app_mentions(body, say, logger): logger.info(body) say("What's up? I'm a Chalice app :wave:")
Bedrockを使用してメンションの内容から返信を作成するコードに置き換えます
- メンションでAppが受け取ったメッセージからメンション部分を削除
- Bedrock で AL21 Labs の Jurassic-2 Mid モデルを使用して応答を生成
- スレッドに返信する
<br />import boto3 import botocore logging.info(f"boto3={boto3.__version__}, botocore={botocore.__version__}") @bolt_app.event("app_mention") def handle_app_mentions(body, say, logger): logger.info(body) event = body["event"] channel = event["channel"] ts = event["ts"] # Slackでメンションを受け取ったらメッセージからメンションを取り除く mention_text = re.sub(r'<@.*?> ', "", event["text"]) # 応答を生成 # Bedrock Clientの作成 bedrock_client = boto3.client('bedrock-runtime') titanInputText = f"{mention_text}\n" bedrock_body = { "prompt": titanInputText, "maxTokens": 200, "temperature": 0.7, "topP": 1, } body_bytes = json.dumps(bedrock_body).encode('utf-8') response = bedrock_client.invoke_model( accept="*/*", body=body_bytes, contentType="application/json", modelId="ai21.j2-mid-v1", ) resp_body = response["body"].read() resp_body_json = json.loads(resp_body.decode('utf-8')) logging.info(resp_body_json["completions"][0]["data"]["text"]) text_prompts = resp_body_json["completions"][0]["data"]["text"] # スレッドに返信 say(f"{text_prompts}", thread_ts = ts)
デプロイ
新しいBoto3を含んだLambdaのLayerも自動で作成して、更新デプロイしてくれるのでとても助かります。
$ chalice deploy ... Creating Rest API Resources deployed: - Lambda Layer ARN: arn:aws:lambda:us-east-1:123456789012:layer:bolt-chalice-bedrock-dev-managed-layer:1 - Lambda ARN: arn:aws:lambda:us-east-1:123456789012:function:bolt-chalice-bedrock-dev - Rest API URL: https://hoge.execute-api.ap-northeast-1.amazonaws.com/api/
動作確認
インストールが正常にいけば、任意の部屋に追加したSlack Appを追加して、メンションしてください。
以下のようにBedrock API からの答えが生成されており、スレッドに返信されていれば成功です
リソース削除
以下コマンドでAWS上のリソースはきれいに削除できます
$ chalice delete
まとめ
以前作ったSlack App を流用して、さくっとBedrock API 使ってSlack App を作成してみました。 Bedrock ではほぼ同じ、APIのインターフェースで様々なモデルがよべるようになるので、いろいろなバリエーションができるかと思います。
プロンプト検証は、Jypter Notebook(SageMaker)などで、行うことが多いと思いますが、デモや共有して検証して貰う際などに流用できるかと思います。
参考情報
Chalice